/**
 * server module
 * 
 * @author strlst <e11907086@student.tuwien.ac.at>
 * @date 2020-01-07
 * @brief contains implementations of the main entry point and auxiliary
 * methods of the server header
 */

#include "server.h"

void die(char *message, char *program, int exit_code) {
    fprintf(stderr, message, program, strerror(errno));
    exit(exit_code);
}

void usage() {
    fprintf(stderr, "usage: server [-c] [-p PORT] [-i INDEX] DOC_ROOT\n");
    exit(EXIT_FAILURE);
}

int main(int argc, char **argv) {
    uint16_t opt_port = 8080;
    char *opt_index = NULL;
    char *opt_doc_root = NULL;
    int opt_compress = 0;

    char c;
    int count = 1;

    /* parse arguments */
    while ((c = getopt(argc, argv, "cp:i:")) != -1) {
        switch (c) {
            case 'p':
                opt_port = strtol(optarg, NULL, 0);
                if (opt_port == 0)
                    usage();
                count += 2;
                break;
            case 'i':
                opt_index = optarg;
                count += 2;
                break;
            case 'c':
                opt_compress = 1;
                count += 1;
                break;
            /* unsupported arugments */
            case '?':
                usage();
                break;
            /* should never happen */
            default:
                assert(0);
        }
    }

    /* there can't be no arguments */
    /* there can only be 1 extra argument, the URL */
    /* the extra argument must be supplied */
    if (argc <= 1 || argc > count + 1 || optind == argc)
        usage();

    opt_doc_root = argv[optind];
    assert(opt_doc_root != NULL);

    /* set default opt_index */
    if (opt_index == NULL)
        opt_index = "index.html";

    /* file can't contain '/' characters */
    if (strchr(opt_index, '/') != NULL)
        die("%s: INDEX must not contain any '/' characters\n", argv[0], EXIT_FAILURE);

    printf("port %u, index %s, doc_root %s, compress %s\n", opt_port, opt_index, opt_doc_root, opt_compress ? "on" : "off");

    /* attempt opening dir */
    DIR* dir = opendir(opt_doc_root);
    if (dir)
        closedir(dir);
    else if (ENOENT == errno)
        die("%s: specified DOC_ROOT directory does not exist\n", argv[0], EXIT_FAILURE);
    else if (EACCES == errno)
        die("%s: no permission to access DOC_ROOT directory\n", argv[0], EXIT_FAILURE);
    else
        die("%s: error opening specified DOC_ROOT\n", argv[0], EXIT_FAILURE);

    /* start receiving requests */
    receive_requests(argv[0], opt_port, opt_doc_root, opt_index, opt_compress);

    return EXIT_SUCCESS;
}